package group2.core.database.impl;

import group2.core.database.IJpaCtrl;
import group2.core.database.NonexistentEntityException;
import group2.core.entities.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.transaction.UserTransaction;

/**
 * Manages the database connection for Comments.
 * 
 * @author cnilsson
 */
public class CommentJpaCtrl implements IJpaCtrl<Comment> {

    // UserTransaction not used in non container (i.e. for now)
    private final UserTransaction utx;
    // Get from Database
    private final EntityManagerFactory emf;

    public CommentJpaCtrl(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }

    @Override
    public void create(Comment t) {
        EntityManager em = getEntityManager();
        try {
            em.getTransaction().begin();
            em.persist(t);
            t.getCommentAuthor().addComment(em.find(Comment.class, t.getId()));
            t.getPost().addComment(em.find(Comment.class, t.getId()));
            em.merge(t.getCommentAuthor());
            em.merge(t.getPost());
            em.getTransaction().commit();
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", e);
            em.getTransaction().rollback();
        } finally {
            em.close();
        }
    }

    @Override
    public void destroy(Long id) throws NonexistentEntityException {
        EntityManager em = getEntityManager();
        try {
            em.getTransaction().begin(); 
            Comment comment = em.find(Comment.class, id);
            comment.getCommentAuthor().removeComment(comment);
            comment.getPost().removeComment(comment);
            em.remove(comment);
            em.getTransaction().commit();
        } finally {
            em.close();
        }
    }

    @Override
    public void edit(Comment t) throws NonexistentEntityException, Exception {
        EntityManager em = getEntityManager();
        try {
            em.getTransaction().begin(); 
            em.merge(t);
            em.getTransaction().commit();
        } finally {
            em.close();
        }
    }

    @Override
    public List<Comment> findEntities() {
        EntityManager em = getEntityManager();
        List<Comment> list = null;

        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<Comment> query = builder.createQuery(Comment.class);
        Root<Comment> c = query.from(Comment.class);
        query.select(c);
        TypedQuery<Comment> q = em.createQuery(query);
        list = q.getResultList();
        if (list == null) {
            list = new ArrayList();
        }
        return list;
    }

    @Override
    public List<Comment> findEntities(int maxResults, int firstResult) {
        List<Comment> list = findEntities();

        if (maxResults >= list.size()) {
            maxResults = list.size();
        }

        if (firstResult + maxResults > list.size()) {
            firstResult = list.size() - maxResults;
        }

        return list.subList(firstResult, firstResult + maxResults);
    }

    @Override
    public Comment findEntity(Long id) {
        Comment c = null;
        EntityManager em = getEntityManager();
        try {
            em.getTransaction().begin();
            c = em.find(Comment.class, id);
            em.getTransaction().commit();
        } finally {
            em.close();
            return c;
        }
    }

    @Override
    public int getEntityCount() {
        return findEntities().size();
    }

    @Override
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }
}
